package xxl.robotlegs.extensions.viewprocessormap.impl 
{
	import flash.utils.Dictionary;
	import xxl.robotlegs.extensions.matching.api.ITypeFilter;
	import xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorConfigurator;
	import xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorMapper;
	import xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorMapping;
	import xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorUnmapper;
	import xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorViewHandler;
	import xxl.robotlegs.framework.api.ILogger;
	/**
	 * ...
	 * @author XXL
	 */
	public class ViewProcessorMapper implements IViewProcessorMapper, IViewProcessorUnmapper
	{
		private const _mappings:Dictionary = new Dictionary();
		private var _handler:IViewProcessorViewHandler;
		private var _matcher:ITypeFilter;
		private var _logger:ILogger;
		
		public function ViewProcessorMapper(matcher:ITypeFilter, handler:IViewProcessorViewHandler, logger:ILogger = null) 
		{
			_handler = handler;
			_matcher = matcher;
			_logger = logger;
		}
		
		private function overwriteMapping(mapping:IViewProcessorMapping, processClassOrInstance:*):IViewProcessorConfigurator
		{
			_logger && _logger.warn("{0} 重复映射到 {1}", [_matcher, mapping]);
			deleteMapping(mapping);
			return createMapping(processClassOrInstance);
		}
		
		private function createMapping(processor:Object):ViewProcessorMapping
		{
			const mapping:ViewProcessorMapping = new ViewProcessorMapping(_matcher, processor);
			_handler.addMapping(mapping);
			_mappings[processor] = mapping;
			_logger && _logger.debug("{0} 映射到 {1}", [_matcher, mapping]);
			return mapping;
		}
		
		private function deleteMapping(mapping:IViewProcessorMapping):void
		{
			_handler.removeMapping(mapping);
			delete _mappings[mapping.processor];
			_logger && _logger.debug("{0} 从 {1} 中取消映射", [_matcher, mapping]);
		}
		
		/* INTERFACE xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorMapper */
		
		public function toProcess(processClassOrInstance:*):IViewProcessorConfigurator 
		{
			const mapping:IViewProcessorMapping = _mappings[processClassOrInstance];
			return mapping
				? overwriteMapping(mapping, processClassOrInstance)
				: createMapping(processClassOrInstance);
		}
		
		public function toInjection():IViewProcessorConfigurator 
		{
			return toProcess(ViewInjectionProcessor);
		}
		
		public function toNoProcess():IViewProcessorConfigurator 
		{
			return toProcess(NullProcessor);
		}
		
		/* INTERFACE xxl.robotlegs.extensions.viewprocessormap.api.IViewProcessorUnmapper */
		
		public function fromProcess(processorClassOrInstance:*):void 
		{
			const mapping:IViewProcessorMapping = _mappings[processorClassOrInstance];
			mapping && deleteMapping(mapping);
		}
		
		public function fromNoProcess():void 
		{
			fromProcess(NullProcessor);
		}
		
		public function fromInjection():void 
		{
			fromProcess(ViewInjectionProcessor);
		}
		
		public function fromAll():void 
		{
			for (var processor:Object in _mappings)
			{
				fromProcess(processor);
			}
		}
		
	}

}